#include "cmd_node.h"

using namespace vpm::cmo;

CmdNode::CmdNode(NodeType type,const std::string & name, const std::string value, CmdNodePtr parent)
{
	index      = 0;
	nodeType   = type; 
	nodeName   = name; 
	nodeValue  = value; 
	nodeParent = parent;	
}

CmdNodePtr CmdNode::find_keyword(const std::string &key)
{
	for (CmdNodes::iterator itr =children.begin(); itr != children.end(); ++itr)
	{
		if (key == (*itr)->nodeName)
		{
			return *itr; 
		}
	}
	return CmdNodePtr(); 
}

std::string CmdNode::prompt_children(int indent)
{
	bool bFlag = false; 
	std::stringstream prompt;
	prompt <<  std::setw(indent) ;
	for (CmdNodes::iterator itr =children.begin(); itr != children.end(); ++itr)
	{
		switch((*itr)->nodeType)
		{
		case KeyWord:
			if (!bFlag )
			{
				prompt <<  "v ";
				bFlag = true; 
			}
			prompt  << (*itr)->nodeName<<" ";
			break;
		case NamedValue:
			if (!bFlag )
			{
				prompt <<  "v ";
				bFlag = true; 
			}
			prompt <<'('<< (*itr)->nodeName <<") "; 
			break;
		case Optional:
			if (!bFlag )
			{
				prompt <<  "v ";
				bFlag = true; 
			}
			prompt  <<'['<< (*itr)->nodeName <<"] "; 
			break; 
		default:
			;
		}			
	}
	return prompt.str();
}

CmdNodes CmdNode::get_matched_nodes(const std::string & key)
{
	CmdNodes matched;

	for (CmdNodes::iterator itr =children.begin(); itr != children.end(); ++itr)
	{			
		if ((*itr)->nodeType == CmdNode::NamedValue)
		{
			if (key.empty())
			{
				return matched; 
			}

			matched.insert(*itr); 
			continue; 
		}

		if ((*itr)->nodeName.length() >= key.length() )
		{
			if (is_match_node(key,(*itr)->nodeName))
			{
				matched.insert(*itr);
			}
		}
	}
	return matched;
}

//test if the short key match the long key
bool CmdNode::is_match_node(const std::string & skey, const std::string & lkey)
{
	const char * pShorter = skey.c_str(); 
	const char * pLonger  = lkey.c_str(); 

	if (*pShorter == '\0')
	{
		return true; 
	}
	const char * p = pShorter; 
	while (*p != 0)
	{
		if (*p != *(pLonger + (p - pShorter)))
		{
			return false; 
		}
		p++;
	}
	return true; 	
}
   
  
 
